#pragma once
#include "cdiwindow.h"
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment( lib, "d3d9.lib")
#pragma comment( lib, "d3dx9.lib")

class CdiD3DWindow : public CdiWindow
{
  // Com interface to create d3d window
  LPDIRECT3D9 m_pD3D;

  // Frame rate variable
  int         m_frameRate;

  // Frame Frequency
  INT64       m_frequency;

protected:
  // Full Screen or not  
  bool  m_bFullScreen;

  // The device
  LPDIRECT3DDEVICE9 m_pDevice;

  // Reset the screen if lost focus
  virtual void ResetScreen();

private:
  // Init Parameters
  virtual void InitD3DParameters( D3DPRESENT_PARAMETERS& d3dParams );

  // Create Device
  virtual HRESULT CreateDevice( D3DPRESENT_PARAMETERS& d3dParams );

protected:
  // Update the frame rate  
  int CalculateFrameRate();

public:
  // Constructors  
  CdiD3DWindow(WNDPROC proc);
  
  CdiD3DWindow(WNDPROC proc, bool fullScreen, int width, int height );

  ~CdiD3DWindow();

public:
  //Methods
  ///////////////////////////

  // Viewport  
  virtual void CreateViewPort();

  // Projection Matrice
  virtual void CreateProjectionMatrice();

  // Set the view Matrix
  virtual inline void SetViewMatrix( D3DXVECTOR3& position, D3DXVECTOR3& lookAt, D3DXVECTOR3& up );
  
public:
  // Methods
  ///////////////////////////
  virtual void Start();

  // Init D3D
  ///////////////////////////
  virtual void InitD3D();

  // Game Loop, must overrid
  ///////////////////////////
  virtual void GameLoop() = 0;

  // Deal with input
  ///////////////////////////
  virtual void HandleInput( UINT Msg, WPARAM wParam, LPARAM lParam ) = 0;

public:
  // Properties
  ///////////////////////////

  // Width
  ///////////////////////////
  void SetWidth( int width ) { m_screenWidth = width;}
  inline int GetWidth() const { return m_screenWidth;}

  // Height
  ///////////////////////////
  void SetHeight( int height ) { m_screenHeight = height; }
  inline int GetHeight() const { return m_screenHeight; }

  // FullScreen
  ///////////////////////////
  void SetFullScreen( bool fullScreen ) { m_bFullScreen = fullScreen; }
  bool IsFullScreen() const { return m_bFullScreen; }

  // Get the Device
  ///////////////////////////
  LPDIRECT3DDEVICE9 GetDevice() const { return (const LPDIRECT3DDEVICE9)m_pDevice; }

  // Get the Frame Rate
  ///////////////////////////
  inline int GetFrameRate() const { return m_frameRate; }

  // Ensure the application is ready to go
  virtual void AssertValid();

  // Enable or disable the lighting
  void SetLightingState(BOOL Enabled);
};
